#include "stdio.h"
#include "signal.h"

#if defined(WIN32) || defined(WIN64)
#include "windows.h"
#endif

#include "pthread.h"

#include <stdlib.h>
#include <math.h>
#include "hw_type.h"
#include "iota_init.h"
#include "iota_cfg.h"

#include "LogUtil.h"
#include "JsonUtil.h"
#include "StringUtil.h"
#include "iota_login.h"
#include "iota_datatrans.h"
#include "string.h"
#include "cJSON.h"
#include "sys/types.h"
#include "unistd.h"
#include "iota_error_type.h"

#include <sys/socket.h>
#include <sys/types.h>          /* See NOTES */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#include<stdio.h>
#include <sys/socket.h>
#include <sys/types.h>          /* See NOTES */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>                      // 广州阴晴西北南风级中雨转雷阵东持续无向℃
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>
/* if you want to use syslog,you should do this:
 *
 * #include "syslog.h"
 * #define _SYS_LOG
 *
 * */

#define DEST_IP "192.168.1.137"
#define DEST_PORT 11000

#define HOST_IP "192.168.1.136"
#define HOST_PORT 15000

static int sendsocketfd;
static int recvsocketfd;

struct sockaddr_in hostaddr;
struct sockaddr_in dest_addr;


char* workPath = ".";
char* gatewayId = NULL;

int alarmValue = 0;

char* serverIp_ = "";
int port_ = 1883;

char* username_ = "66727aaa7dbfd46fabc10148_myNodeId";//deviceId66727aaa7dbfd46fabc10148_myNodeId
char* password_ = "01234567";//600a9852942d2302db444b53_12334353

int disconnected_ = 0;

char *subDeviceId = "f6cd4bbb1a8ab53acbb595efd0e90199_ABC123456789";

int sleepTime = 5000;

char from6818[64];
char tempertature[8]={0},smoke[8]={0},humitidy[8]={0};

char data [2048]={0};

extern int extract_json(const char*http_response);
extern int analyzeweather(char*http_response);

void timeSleep(int ms)
{
#if defined(WIN32) || defined(WIN64)
    Sleep(ms);
#else
    usleep(ms * 1000);
#endif
}


//------------------------------------------------------Test  data report---------------------------------------------------------------------

void Test_messageReport()
{
	int messageId = IOTA_MessageReport(NULL, "data123", "123", "hello");
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_messageReport() failed, messageId %d\n", messageId);
	}
}

/*

				制作上报json数据并上报

*/
void Test_propertiesReport()
{
	int serviceNum = 1;//����Ҫ�ϱ���service����
	ST_IOTA_SERVICE_DATA_INFO services[serviceNum];

	JSON * sendroot =  JSON_Parse(from6818);  //Convert string to JSON

	strcpy(tempertature, JSON_GetStringFromObject(sendroot, "temperature", "-1"));
	strcpy(smoke, JSON_GetStringFromObject(sendroot, "smoke", "-1")); 
	strcpy(humitidy, JSON_GetStringFromObject(sendroot, "humitidy", "-1")); 

	double t = strtod(tempertature, NULL);
	double s = strtod(smoke, NULL);
	double h = strtod(humitidy, NULL);


	cJSON *root;
	root = cJSON_CreateObject();
	cJSON_AddNumberToObject(root, "alarm", 0);
	cJSON_AddNumberToObject(root, "smokeConcentration", s);
	cJSON_AddNumberToObject(root, "temperature", t);
	cJSON_AddNumberToObject(root, "humidity", h);
	
	char *payload;
	payload = cJSON_Print(root);
	cJSON_Delete(root);

	services[0].event_time = NULL;//getEventTimeStamp(); //if event_time is set to NULL, the time will be the iot-platform's time.
	services[0].service_id = "smokeDetector";
	services[0].properties = payload;

	int messageId = IOTA_PropertiesReport(services, serviceNum);
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_batchPropertiesReport() failed, messageId %d\n", messageId);
	}
	free(payload);
}

void Test_batchPropertiesReport()
{
	int deviceNum = 1;      //Ҫ�ϱ������豸�ĸ���
	ST_IOTA_DEVICE_DATA_INFO devices[deviceNum]; //���豸Ҫ�ϱ��Ľṹ������
	int serviceList[deviceNum];  //��Ӧ�洢ÿ�����豸Ҫ�ϱ��ķ������
    serviceList[0] = 2;       //���豸һҪ�ϱ���������
	//	serviceList[1] = 1;		  //���豸��Ҫ�ϱ�һ������


    char *device1_service1 = "{\"Load\":\"1\",\"ImbA_strVal\":\"3\"}"; //service1Ҫ�ϱ����������ݣ�������json��ʽ

    char *device1_service2 = "{\"PhV_phsA\":\"2\",\"PhV_phsB\":\"4\"}";//service2Ҫ�ϱ����������ݣ�������json��ʽ

	devices[0].device_id = subDeviceId;
	devices[0].services[0].event_time = getEventTimeStamp();
	devices[0].services[0].service_id = "parameter";
	devices[0].services[0].properties = device1_service1;


	devices[0].services[1].event_time = getEventTimeStamp();
	devices[0].services[1].service_id = "analog";
	devices[0].services[1].properties = device1_service2;



	//	char *device2_service1 = "{\"AA\":\"2\",\"BB\":\"4\"}";
	//	devices[1].device_id = "subDevices22222";
	//	devices[1].services[0].event_time = "d2s1";
	//	devices[1].services[0].service_id = "device2_service11111111";
	//	devices[1].services[0].properties = device2_service1;


	int messageId = IOTA_BatchPropertiesReport(devices, deviceNum, serviceList);
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_batchPropertiesReport() failed, messageId %d\n", messageId);
	}

}

void Test_commandResponse(char *requestId)
{
	char *pcCommandRespense = "{\"cmdRsp\":\"success\"}";  //just test response

	int result_code = 0;
	char *response_name = NULL;

	int messageId = IOTA_CommandResponse(requestId, result_code, response_name, pcCommandRespense);
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_commandResponse() failed, messageId %d\n", messageId);
	}

}

void Test_propSetResponse(char *requestId)
{
	int messageId = IOTA_PropertiesSetResponse(requestId, 0, "success");
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_propSetResponse() failed, messageId %d\n", messageId);
	}

}

void Test_propGetResponse(char *requestId)
{
	int serviceNum = 2;
	ST_IOTA_SERVICE_DATA_INFO serviceProp[serviceNum];

	char *property = "{\"Load\":\"5\",\"ImbA_strVal\":\"6\"}";

	serviceProp[0].event_time = getEventTimeStamp();
	serviceProp[0].service_id = "parameter";
	serviceProp[0].properties = property;

	char *property2 = "{\"PhV_phsA\":\"2\",\"PhV_phsB\":\"4\"}";

	serviceProp[1].event_time = getEventTimeStamp();
	serviceProp[1].service_id = "analog";
	serviceProp[1].properties = property2;

	int messageId = IOTA_PropertiesGetResponse(requestId, serviceProp, serviceNum);
	if(messageId != 0)
	{
		printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: Test_propGetResponse() failed, messageId %d\n", messageId);
	}
}

//--------------------------------------------------------------------------------------------------------------------------------------------------

void handleAuthSuccess(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleConnectSuccess(), login success\n");
    disconnected_ = 0;
}

void handleAuthFailure(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: handleConnectFailure() error, messageId %d, code %d, messsage %s\n", messageId, code, message);
    //judge if the network is available etc. and login again
    //...
    printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: handleConnectFailure() login again\n");
    int ret = IOTA_Connect();
    if (ret != 0)
    {
        printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: handleConnectionLost() error, login again failed, result %d\n", ret);
    }
}

void handleConnectionLost(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_WARNING, "AgentLiteDemo: handleConnectionLost() warning, messageId, code %d, messsage %s\n",messageId, code, message);
    //judge if the network is available etc. and login again
    //...
    int ret = IOTA_Connect();
    if (ret != 0)
    {
        printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: handleConnectionLost() error, login again failed, result %d\n", ret);
    }
}

void handleDisAuthSuccess(void* context, int messageId, int code, char *message)
{
    disconnected_ = 1;

    printf("AgentLiteDemo: handleLogoutSuccess, login again\n");
    printf("AgentLiteDemo: handleDisAuthSuccess(), messageId %d, code %d, messsage %s\n", messageId, code, message);
}

void handleDisAuthFailure(void* context, int messageId, int code, char *message)
{
    printf("AgentLiteDemo: handleLogoutFailure, login again\n");
    int ret = IOTA_Connect();
    if (ret != 0)
    {
        printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: handleConnectionLost() error, login again failed, result %d\n", ret);
    }
    printf("AgentLiteDemo: handleDisAuthFailure(), messageId %d, code %d, messsage %s\n", messageId, code, message);
}

void handleSubscribesuccess(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleSubscribesuccess() messageId %d\n", messageId);
}

void handleSubscribeFailure(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_WARNING, "AgentLiteDemo: handleSubscribeFailure() warning, messageId %d, code %d, messsage %s\n", messageId, code, message);
}

void handlePublishSuccess(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePublishSuccess() messageId %d\n", messageId);
}

void handlePublishFailure(void* context, int messageId, int code, char *message)
{
    printfLog(EN_LOG_LEVEL_WARNING, "AgentLiteDemo: handlePublishFailure() warning, messageId %d, code %d, messsage %s\n", messageId, code, message);
}

//-------------------------------------------handle  message   arrived------------------------------------------------------------------------------

void handleMessageDown(void* context, int messageId, int code, char *message)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleMessageDown(), messageId %d, code %d, messsage %s\n", messageId, code, message);

	JSON * root =  JSON_Parse(message);  //Convert string to JSON

	char* content = JSON_GetStringFromObject(root, "content", "-1");     //get value of content
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleMessageDown(), content %s\n", content);

	char* object_device_id = JSON_GetStringFromObject(root, "object_device_id", "-1");     //get value of object_device_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleMessageDown(), object_device_id %s\n", object_device_id);

	char* name = JSON_GetStringFromObject(root, "name", "-1");     //get value of name
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleMessageDown(), name %s\n", name);

	char* id = JSON_GetStringFromObject(root, "id", "-1");        //get value of id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleMessageDown(), id %s\n", id);

	JSON_Delete(root);

}


/*----------------------------------------



			处理下发命令     猜测-1表示以字符串格式为返回值，无表示以json格式为返回值，1表示以整型格式为返回值



---------------------------------------------------*/


void handleCommandRequest(void* context, int messageId, int code, char *message, char *requestId)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), messageId %d, code %d, messsage %s, requestId %s\n", messageId, code, message, requestId);

	JSON * root =  JSON_Parse(message);  //Convert string to JSON

	char* object_device_id = JSON_GetStringFromObject(root, "object_device_id", "-1");     //get value of object_device_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), object_device_id %s\n", object_device_id);

	char* service_id = JSON_GetStringFromObject(root, "service_id", "-1");     //get value of service_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), content %s\n", service_id);

	char* command_name = JSON_GetStringFromObject(root, "command_name", "-1");     //get value of command_name
	
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), name %s\n", command_name);

	JSON* paras = JSON_GetObjectFromObject(root, "paras");       //get value of data
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), id %s\n", paras);

	if(!strcmp(command_name,"onLed"))
	{
		if (JSON_GetIntFromObject(paras, "value", 1))
		{
			printf("get commend onled\n");
			udpsendstr("turnonaircondition");
		}else if(!(JSON_GetIntFromObject(paras, "value", 1)))
		{
			printf("get commend offled\n");

			udpsendstr("turnoffaircondition");
		}
	}

	if (paras)
	{
		sleepTime = JSON_GetIntFromObject(paras, "value", 1) * 1000;

		printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleCommandRequest(), sleepTime %d\n", sleepTime);
	}

	Test_commandResponse(requestId);     //command reponse

	JSON_Delete(root);

}

void handlePropertiesSet(void* context, int messageId, int code, char *message, char *requestId)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), messageId %d, code %d, messsage %s, requestId %s\n", messageId, code, message, requestId);

	JSON * root =  JSON_Parse(message);  //Convert string to JSON

	char* object_device_id = JSON_GetStringFromObject(root, "object_device_id", "-1");     //get value of object_device_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), object_device_id %s\n", object_device_id);

	JSON* services = JSON_GetObjectFromObject(root, "services");                            //get  services array
 	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), services %s\n", services);

	int dataSize = JSON_GetArraySize(services);                                            //get length of services array
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), dataSize %d\n", dataSize);


	if (dataSize > 0)
	{
		JSON* service = JSON_GetObjectFromArray(services, 0);                //only get the first one to demonstrate
		printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleSubDeviceMessageDown(), service %s\n", service);
		if (service)
		{
			char *service_id = JSON_GetStringFromObject(service, "service_id", NULL);

			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), service_id %s\n", service_id);

			JSON* properties = JSON_GetObjectFromObject(service, "properties");

			alarmValue = JSON_GetIntFromObject(properties, "alarm", NULL);
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesSet(), alarmValue %d\n", alarmValue);
		}
	}

	Test_propSetResponse(requestId);  //command response

	JSON_Delete(root);
}

void handlePropertiesGet(void* context, int messageId, int code, char *message, char *requestId)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesGet(), messageId %d, code %d, messsage %s, requestId %s\n", messageId, code, message, requestId);

	JSON * root =  JSON_Parse(message);

	char* object_device_id = JSON_GetStringFromObject(root, "object_device_id", "-1");     //get value of object_device_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesGet(), object_device_id %s\n", object_device_id);

	char* service_id = JSON_GetStringFromObject(root, "service_id", "-1");     //get value of service_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handlePropertiesGet(), service_id %s\n", service_id);

	Test_propGetResponse(requestId);  //command response

	JSON_Delete(root);
}

void handleDeviceProGetResp(void* context, int messageId, int code, char *message, char *requestId)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleDeviceProGetResp(), messageId %d, code %d, messsage %s, requestId %s\n", messageId, code, message, requestId);
	//start to reponse  command  by the topic  of $oc/devices/{device_id}/sys/commands/response/request_id={request_id}
}


void handleEventsDown(void* context, int messageId, int code, char *message)
{
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleSubDeviceMessageDown(), messageId %d, code %d, messsage %s\n", messageId, code, message);


	// the demo of how to get the parameter
	JSON * root =  JSON_Parse(message);

	char* object_device_id = JSON_GetStringFromObject(root, "object_device_id", "-1");           //get value of object_device_id
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), object_device_id %s\n", object_device_id);

	JSON* service = JSON_GetObjectFromObject(root, "services");                                 //get object of services
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), services %s\n", service);

	int dataSize = JSON_GetArraySize(service);                                                 //get size of services
	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), dataSize %d\n", dataSize);

	if (dataSize > 0)
	{
		JSON* serviceEvent = JSON_GetObjectFromArray(service, 0);                              //get object of ServiceEvent
		printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), serviceEvent %s\n", serviceEvent);
		if (serviceEvent)
		{
			char * service_id = JSON_GetStringFromObject(serviceEvent, "service_id", NULL);    //get value of service_id
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), service_id %s\n", service_id);

			char *event_type = NULL; //To determine whether to add or delete a sub device
			event_type = JSON_GetStringFromObject(serviceEvent, "event_type", NULL);    //get value of event_type
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), event_type %s\n", event_type);

			char * event_time = JSON_GetStringFromObject(serviceEvent, "event_time", NULL);    //get value of event_time
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), event_time %s\n", event_time);

			JSON* paras = JSON_GetObjectFromObject(serviceEvent, "paras");                              //get object of paras
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), paras %s\n", paras);

			JSON* devices = JSON_GetObjectFromObject(paras, "devices");                                 //get object of devices
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), devices %s\n", devices);

			int version = JSON_GetIntFromObject(paras, "version", -1);                             //get value of version
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), version %d\n", version);

			int devicesSize = JSON_GetArraySize(devices);                                                 //get size of devicesSize
			printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), devicesSize %d\n", devicesSize);

			if (devicesSize > 0)
			{
				JSON* deviceInfo = JSON_GetObjectFromArray(devices, 0);                                 //get object of deviceInfo
				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), deviceInfo %s\n", deviceInfo);

				char * parent_device_id = JSON_GetStringFromObject(serviceEvent, "parent_device_id", NULL);    //get value of parent_device_id
				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), parent_device_id %s\n", parent_device_id);

				char * node_id = JSON_GetStringFromObject(serviceEvent, "node_id", NULL);    //get value of node_id
				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), node_id %s\n", node_id);

				subDeviceId = JSON_GetStringFromObject(serviceEvent, "device_id", NULL);    //get value of device_id
				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), device_id %s\n", subDeviceId);

                if (!strcmp(event_type, "add_sub_device_notify"))          //add a sub device
                {
    				char * name = JSON_GetStringFromObject(serviceEvent, "name", NULL);    //get value of name
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), name %s\n", name);

    				char * description = JSON_GetStringFromObject(serviceEvent, "description", NULL);    //get value of description
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), description %s\n", description);

    				char * manufacturer_id = JSON_GetStringFromObject(serviceEvent, "manufacturer_id", NULL);    //get value of manufacturer_id
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), manufacturer_id %s\n", manufacturer_id);

    				char * model = JSON_GetStringFromObject(serviceEvent, "model", NULL);    //get value of model
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), model %s\n", model);

    				char * product_id = JSON_GetStringFromObject(serviceEvent, "product_id", NULL);    //get value of product_id
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), product_id %s\n", product_id);

    				char * fw_version = JSON_GetStringFromObject(serviceEvent, "fw_version", NULL);    //get value of fw_version
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), fw_version %s\n", fw_version);

    				char * sw_version = JSON_GetStringFromObject(serviceEvent, "sw_version", NULL);    //get value of sw_version
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), sw_version %s\n", sw_version);

    				char * status = JSON_GetStringFromObject(serviceEvent, "status", NULL);    //get value of status
    				printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), status %s\n", status);


    				Test_batchPropertiesReport(); //command response

                }
                else if(!strcmp(event_type, "delete_sub_device_notify"))    //delete a sub device
                {
                	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), delete a sub device.\n");
                }
                else
                {
                	printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: handleEventsDown(), default.\n");
                }

			}

		}
	}

	JSON_Delete(root);
}

void setConnectConfig(){

	FILE *file;
	long length;
	char *content;
	cJSON *json;

	file=fopen("./ClientConf.json","rb");
	fseek(file,0,SEEK_END);
	length = ftell(file);
	fseek(file,0,SEEK_SET);
	content = (char*)malloc(length+1);
	fread(content,1,length,file);
	fclose(file);

	json = cJSON_Parse(content);

	username_ = JSON_GetStringFromObject(json, "deviceId", NULL);
	password_ = JSON_GetStringFromObject(json, "secret", NULL);
	char *url = JSON_GetStringFromObject(json, "serverUri", NULL);

	deleteSubStr(url,"ssl://");
	deleteSubStr(url,":8883");

	serverIp_ = url;
}


//----------------------------------------------------------------------------------------------------------------------------------------------

void setAuthConfig()
{
    IOTA_ConfigSetStr(EN_IOTA_CFG_MQTT_ADDR, serverIp_);
    IOTA_ConfigSetUint(EN_IOTA_CFG_MQTT_PORT, port_);
    IOTA_ConfigSetStr(EN_IOTA_CFG_DEVICEID, username_);
    IOTA_ConfigSetStr(EN_IOTA_CFG_DEVICESECRET, password_);

#ifdef _SYS_LOG
    IOTA_ConfigSetUint(EN_IOTA_CFG_LOG_LOCAL_NUMBER, LOG_LOCAL7);
    IOTA_ConfigSetUint(EN_IOTA_CFG_LOG_LEVEL, LOG_INFO);
#endif
}

void setMyCallbacks()
{
    IOTA_SetCallback(EN_IOTA_CALLBACK_CONNECT_SUCCESS, handleAuthSuccess);
    IOTA_SetCallback(EN_IOTA_CALLBACK_CONNECT_FAILURE, handleAuthFailure);
    IOTA_SetCallback(EN_IOTA_CALLBACK_CONNECTION_LOST, handleConnectionLost);

    IOTA_SetCallback(EN_IOTA_CALLBACK_DISCONNECT_SUCCESS, handleDisAuthSuccess);
    IOTA_SetCallback(EN_IOTA_CALLBACK_DISCONNECT_FAILURE, handleDisAuthFailure);

    IOTA_SetCallback(EN_IOTA_CALLBACK_SUBSCRIBE_SUCCESS, handleSubscribesuccess);
    IOTA_SetCallback(EN_IOTA_CALLBACK_SUBSCRIBE_FAILURE, handleSubscribeFailure);

    IOTA_SetCallback(EN_IOTA_CALLBACK_PUBLISH_SUCCESS, handlePublishSuccess);
    IOTA_SetCallback(EN_IOTA_CALLBACK_PUBLISH_FAILURE, handlePublishFailure);


    IOTA_SetCallback(EN_IOTA_CALLBACK_MESSAGE_DOWN, handleMessageDown);
    IOTA_SetCallbackWithTopic(EN_IOTA_CALLBACK_COMMAND_REQUEST, handleCommandRequest);
    IOTA_SetCallbackWithTopic(EN_IOTA_CALLBACK_PROPERTIES_SET, handlePropertiesSet);
    IOTA_SetCallbackWithTopic(EN_IOTA_CALLBACK_PROPERTIES_GET, handlePropertiesGet);
    IOTA_SetCallback(EN_IOTA_CALLBACK_SUB_DEVICE_MESSAGE_DOWN, handleEventsDown);

}

void myPrintLog(int level, char* format, va_list args)
{
    vprintf(format, args); //��־��ӡ�ڿ���̨
/*if you want to printf log in system log files,you can do this:
 *
 * vsyslog(level, format, args);
 * */
}


int extract_json(const char *http_response) {
    // 找到HTTP头部的结束位置
    const char *header_end = strstr(http_response, "\r\n\r\n");
    if (!header_end) {
        fprintf(stderr, "HTTP header not found.\n");
        return 0;
    }
    header_end += 4; // 跳过两个换行符

    // 用于存储JSON数据的字符串
    char *json_data = NULL;
    size_t json_len = 0;
    size_t json_capacity = 2048; // 初始容量

    // 动态扩展以存储JSON数据
    json_data = (char *)malloc(json_capacity);
    if (!json_data) {
        perror("Failed to allocate memory for JSON data");
        return 0;
    }

    // 遍历HTTP响应中的每个chunk
    const char *chunk_start = header_end;
    while (1) {
        const char *chunk_end = strstr(chunk_start, "\r\n");
        if (!chunk_end) {
            fprintf(stderr, "Chunk delimiter not found.\n");
            free(json_data);
            return 0;
        }

        // 将十六进制的chunk长度转换为实际长度
        size_t chunk_len = strtol(chunk_start, NULL, 16);

        // 如果chunk长度为0，表示所有数据已经读取完毕
        if (chunk_len == 0) {
            break;
        }

        // 检查是否需要扩展JSON数据的容量
        if (json_len + chunk_len + 1 > json_capacity) {
            size_t new_capacity = json_capacity * 2;
            while (json_len + chunk_len + 1 > new_capacity) {
                new_capacity *= 2;
            }
            char *new_json_data = (char *)realloc(json_data, new_capacity);
            if (!new_json_data) {
                perror("Failed to reallocate memory for JSON data");
                free(json_data);
                return 0;
            }
            json_capacity = new_capacity;
            json_data = new_json_data;
        }

        // 复制当前chunk的数据到JSON字符串
        memcpy(json_data + json_len, chunk_end + 2, chunk_len);
        json_len += chunk_len;
        json_data[json_len] = '\0'; // 确保字符串以空字符结尾

        // 跳过当前chunk的数据和之后的换行符
        chunk_start = chunk_end + 2 + chunk_len + 2;
    }
	strcpy(data,json_data);
    return 0;
}


int getweather()
{
    //char data [2048]={0};

    //1 根据域名获取阿里云的IP地址  ali-weather.showapi.com
    struct hostent *he = gethostbyname("apis.juhe.cn");
    if(he == NULL)
    {
        perror("DNS查询失败");
        exit(0);
    }

    printf("IP: %s\n", inet_ntoa(*(struct in_addr*)((he->h_addr_list)[0])));

   // printf("ip = %s\n",ip);
    //2 创建TCP套接字
    int socketfd = socket(AF_INET,SOCK_STREAM, 0);
    if(socketfd == -1)
    {
        perror("socket");
        return -1;
    }

    //3 连接服务器   -需要服务器的IP地址和端口号
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET; //IPV4地址协议
    serveraddr.sin_port = htons(80); //服务器端口号 --网络端口号
    serveraddr.sin_addr = *(struct in_addr*)((he->h_addr_list)[0]); //服务器IP --网络IP  公网IP

    int ret = connect(socketfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
    if(ret == -1)
    {
        perror("connect error");
        return -1;
    }

    printf("连接服务器成功.........\n");

    //4 应用层 组合 HTTP数据包
    //Host：用于指明服务器的主机名称
    //curl -i -k --get --include 'https://ali-weather.showapi.com/hour24?area=%E4%B8%BD%E6%B1%9F&areaCode=areaCode'  -H 'Authorization:APPCODE 你自己的AppCode'
    //curl -k -i "http://apis.juhe.cn/simpleWeather/query?key=key&city=%E8%8B%8F%E5%B7%9E"%E5%B9%BF%E5%B7%9E
    char *httpdata = "GET http://apis.juhe.cn/simpleWeather/query?key=e691c52a4168e4c889c8802711c33b6d&city=%E5%B9%BF%E5%B7%9E HTTP/1.1\r\n"
                     "Host:apis.juhe.cn\r\n"
                     "Authorization:APPCODE \r\n\r\n";;

    int getcnt = 0;
   
    //5 发起HTTP请求  --write/send
    ret =  write(socketfd,httpdata,strlen(httpdata));
    printf("write %d bytes\n",ret);

    //6 等待服务器应答--接收服务器的数据
    char recvdata[1024*6] = {0};
    ret = read(socketfd,recvdata,sizeof(recvdata));
    printf("read %d bytes\n",ret);
    //printf("\n");
    // char data[2048]={0};
    strcpy(data,recvdata);
    printf("%s\n",data);
    pthread_t extrtid;

    extract_json(data);
    // data= extract_json(recvdata);
    printf("%s\n",data);
    printf("\n");
    
    //7 解析数据
    //analyzeweather(data);
	udpsendstr(data);
    // sleep(30);
    // getcnt ++;
    // if(getcnt>20)
    //     break;
    
    

    //8 关闭套接字
    close(socketfd);
    
    return 0;
}

int udpsendstr(char* data)
{
    pthread_detach(pthread_self());
    char buf[1024] = {0};
    printf("senddata: %s\n",data);
    strcpy(buf,data);
    // scanf("%s",buf);

    int ret = sendto(sendsocketfd, buf, strlen(buf),0,
                (struct sockaddr*)&dest_addr,sizeof(dest_addr));
    if(ret == -1)
    {
        perror("sendto error");
        return 1;
    }

    printf("sendto ret:%d\n",ret);
    sleep(1);
    return 0;
}

void recv_routine(void)
{
    printf("recvtid\n");
    //2 接收数据
    while (1)
    {
        printf("jjj\n");

		char buf[2048] = {0};
		struct sockaddr_in addr;
		int addrlen = sizeof(addr); //一定要赋值

		int ret = recvfrom(recvsocketfd, buf, sizeof(buf),0,(struct sockaddr*)&addr,&addrlen);
		if(ret == -1)
		{
				perror("recvfrom error");
				break;
		}
		printf("IP:[%s] Port:[%d]recvfrom:%s ret:%d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), buf,ret);
		if(!strcmp(buf,"getweather"))
		{
			getweather();
		}else {
		strcpy(from6818,buf);
		}

    	printf("IP:[%s] Port:[%d]recvfrom:%s ret:%d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), from6818,ret);

       //转发数据
    }
}

int main(int argc, char **argv)
{
#if defined(_DEBUG)
    setvbuf(stdout, NULL, _IONBF, 0); //in order to make the console log printed immediately at debug mode
#endif


    IOTA_SetPrintLogCallback(myPrintLog);

    setConnectConfig();

    printfLog(EN_LOG_LEVEL_INFO, "AgentLiteDemo: start test ===================>\n");

    if (IOTA_Init(workPath) > 0)
    {
        printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: IOTA_Init() error, init failed\n");
        return 1;
    }

    setAuthConfig();
    setMyCallbacks();

    //see handleLoginSuccess and handleLoginFailure for login result
    int ret = IOTA_Connect();
    if (ret != 0)
    {
        printfLog(EN_LOG_LEVEL_ERROR, "AgentLiteDemo: IOTA_Auth() error, Auth failed, result %d\n", ret);
    }

	//1.创建套接字
    sendsocketfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sendsocketfd == -1)
    {
        perror("socket");
        return -1;
    }
    recvsocketfd = socket(AF_INET,SOCK_DGRAM,0);
    if(recvsocketfd == -1)
    {
        perror("socket");
        return -1;
    }

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(DEST_PORT);
    dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);

    hostaddr.sin_family = AF_INET;
    hostaddr.sin_port = htons(HOST_PORT);
    hostaddr.sin_addr.s_addr = inet_addr(HOST_IP);

    //2 绑定
    int my_ret = bind(recvsocketfd,(struct sockaddr*)&hostaddr,sizeof(hostaddr));
    if(ret == -1)
    {
        perror("bind error");
        return -1;
    }

    // pthread_t sendtid;
    // pthread_create(&sendtid,NULL,udpsendstr,"aaaaaaa");
	pthread_t recvtid;
    pthread_create(&recvtid,NULL,recv_routine,NULL);

	//getweather();

    timeSleep(1500);
    int count = 0;
    while(count < 10000)
    {

//        //message up
//        Test_messageReport();

        //properties report
        Test_propertiesReport();

//        //batchProperties report
//        Test_batchPropertiesReport();
//
//        //command response
//        Test_commandResponse("1005");
//
//        timeSleep(1500);
//
//        //propSetResponse
//        Test_propSetResponse("1006");
//
//        timeSleep(1500);
//
//        //propSetResponse
//        Test_propGetResponse("1007");

        timeSleep(sleepTime);

        count++;
    }

    while (1)
	{
		timeSleep(50);
	}

    return 0;
}

